package com.cndw.kungfu.config;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.cndw.commons.util.BlankUtils;
import com.cndw.commons.util.DateFormatUtils;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.ext.StringProcesser;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.vo.ModeRecordVO;

/**
 * 系统后台相关配置信息
 * 
 * @author fantadust
 * @date 2011-5-18 上午10:16:33
 */
public class ConstantsConfig {

	/**
	 * 广告敏感字
	 */
	private static List<String> adWorld;
	/**
	 * 一次敏感立即过滤
	 */
	private static List<String> adWorldDanger;

	/**
	 * 脏话过滤字
	 */
	private static List<String> badWorld;
	/**
	 * 正则匹配敏感词
	 */
	private static String badWorldExp;
	/**
	 * 武林大会刷新启动时间
	 */
	private static String challengeBeginTime;

	/**
	 * 聊天时间间隔
	 */
	private static int chatIntervalSeconds;
	/**
	 * 聊天最大长度
	 */
	private static int chatLengthMax;

	/**
	 * 创建名字的正则
	 */
	private static String commCreateNameExp;
	/**
	 * 最多好友分组个数
	 */
	private static int friendGroupMax;
	/**
	 * 好友最大个数
	 */
	private static int friendNumMax;
	/**
	 * 配置根目录
	 */
	private static String localeResource = "resource/";
	/**
	 * 信件长度相关
	 */
	private static int mailContentLength;
	private static int mailContentLengthMax;
	private static int mailTitleLength;
	private static int mailTitleLengthMax;
	/**
	 * 注册最小长度
	 */
	private static int nameLength;

	/**
	 * 注册最大长度
	 */
	private static int nameLengthMax;
	/**
	 * 声望等级的名称
	 */
	@Deprecated
	private static String[] prestigeNames;
	/**
	 * 声望等级的要求值
	 */
	private static int[] prestigeValues;
	/**
	 * 商城三类物品id
	 */
	private static int[] shopHotIds;

	private static int[] shopNewIds;

	public static final String SYS_INSTRUCTOR = "sysInstructor";

	public static final String SYS_LOCK_CHAT = "sysLockChat";

	public static final String SYS_LOCK_IP = "sysLockIp";

	public static final String SYS_LOCK_PLAYERID = "sysLockPlayerId";
	private static int sysAccessFlag;

	/**
	 * 系统一分钟同步多少次数据库
	 */
	private static int sysAysncSpeedMinute;
	/**
	 * 一次同步开多少个线程(x次数据库执行)
	 */
	private static int sysAysncThreads;
	/**
	 * 暑期活动开关
	 */
	private static int sysCgAtivity;
	/**
	 * 系统自增id统一后缀
	 */
	private static int sysCgAutoNumberSuffix;
	/**
	 * 大区所在ip
	 */
	private static List<String> sysCgCrossIP;
	/**
	 * 平台地址
	 */
	private static String sysCgCrossURL;
	/**
	 * 游戏跨服大区id
	 */
	private static int sysCgCrossServiceId;
	/**
	 * 用户缓存内存回收策略等级
	 */
	private static int sysCgGcLevel;
	/**
	 * 登录的key
	 */
	private static String sysCgKeyLogin;
	/**
	 * 充值的key
	 */
	private static String sysCgKeyPay;
	/**
	 * 平台key
	 */
	private static String sysCgKeyPlatform;
	/**
	 * 开服时间
	 */
	private static String sysCgOpenTime;
	/**
	 * 服务器运营商标志
	 */
	private static String sysCgPartnerEName;
	/**
	 * 元宝兑换比例
	 */
	private static int sysCgPayRate;
	/**
	 * 服务器数字id
	 */
	private static int sysCgServiceId;
	/**
	 * 服务器字符标志
	 */
	private static String sysCgSvrId;
	/**
	 * 腾讯自动分配的服务器编号
	 */
	private static int sysCgWorldId;
	/**
	 * 系统维护开关
	 */
	private static boolean sysClosed;
	/**
	 * 内测帐号
	 */
	private static Set<String> sysGmAccountName;
	/**
	 * 接口平台ip控制
	 */
	private static List<String> sysGmIp;
	/**
	 * 教官账号
	 */
	private static List<String> sysGmInstructor;
	/**
	 * 是否进行防沉迷检查
	 */
	private static boolean sysInspectAddicted;
	/**
	 * 通用检查配置
	 */
	private static int sysInspectComm;
	/**
	 * 是否对人物移动坐标做效验
	 */
	private static boolean sysInspectMove;
	/**
	 * 是否检测场景传送
	 */
	private static boolean sysInspectScene;
	/**
	 * 指导员(instructor)帐号
	 */
	private static Set<Long> sysInstructor;
	/**
	 * 禁言的用户Id
	 */
	private static Map<Long, Integer> sysLockChat;
	/**
	 * 禁言的ip
	 */
	private static List<String> sysLockChatIP;
	/**
	 * 禁言的帐号
	 */
	private static List<String> sysLockChatAcc;

	/**
	 * 封禁的ip
	 */
	private static List<String> sysLockIp;
	/**
	 * 封禁的用户id
	 */
	private static Map<Long, Integer> sysLockPlayerId;
	/**
	 * 新手村有多少个线路
	 */
	private static int sysSubLineNum;
	/**
	 * 多人人數後就切換線路
	 */
	private static int sysSubLineOverflow;

	/**
	 * 分线每条承载人数
	 */
	private static int sysSubLinePlayers;
	/**
	 * 最大可接任务数
	 */
	private static int taskAcceptMax;
	/**
	 * 日常任务次数
	 */
	private static int taskDayNumsDaily;
	/**
	 * 押镖任务的个数
	 */
	private static int taskDayNumsDart;
	/**
	 * 声望任务次数
	 */
	private static int taskDayNumsPrestige;
	/**
	 * 跑环任务次数
	 */
	private static int taskDayNumsUnion;
	private static int unionCreateAsset;
	private static int[] unionJobsFlag;
	/**
	 * 建立帮派的名称长度要求
	 */
	private static int unionNameLength;
	private static int unionNameLengthMax;

	/**
	 * 格式化数据保存
	 * 
	 * @param players
	 * @return
	 */
	public static String format(Map<Long, Integer> players) {
		StringBuilder sb = new StringBuilder();

		Iterator<Map.Entry<Long, Integer>> iterator = players.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<Long, Integer> entry = iterator.next();
			sb.append(entry.getKey());
			sb.append(":");
			sb.append(entry.getValue());
			if (iterator.hasNext()) {
				sb.append("\r\n");
			}
		}

		return sb.toString();

	}

	/**
	 * 格式化数据保存
	 * 
	 * @param players
	 * @return
	 */
	public static String format(Set<Long> players) {
		StringBuilder sb = new StringBuilder();

		Iterator<Long> iterator = players.iterator();
		while (iterator.hasNext()) {
			sb.append(iterator.next());
			if (iterator.hasNext()) {
				sb.append(",");
			}
		}
		return sb.toString();
	}

	public static List<String> getAdWorld() {
		return adWorld;
	}

	
	public static List<String> getAdWorldDanger() {
		return adWorldDanger;
	}

	public static List<String> getBadWorld() {
		return badWorld;
	}

	public static String getBadWorldExp() {
		return badWorldExp;
	}

	public static int getChallengeBeginTime() {
		if (BlankUtils.isBlank(challengeBeginTime)) {
			return TimeProcesser.getUnixTime();
		} else {
			return TimeProcesser.getUnixTime(DateFormatUtils.parseDateTime(challengeBeginTime));
		}
	}

	public static int getChatIntervalSeconds() {
		return chatIntervalSeconds;
	}

	public static int getChatLengthMax() {
		return chatLengthMax;
	}

	public static Type getCollectionType(Field e) {
		Type aType = String.class;
		Type type = e.getType();
		if (type instanceof ParameterizedType) {
			ParameterizedType paramType = (ParameterizedType) type;
			Type[] actualTypes = paramType.getActualTypeArguments();
			aType = actualTypes[0];
		}
		return aType;
	}

	public static String getCommCreateNameExp() {
		return commCreateNameExp;
	}

	public static int getFriendGroupMax() {
		return friendGroupMax;
	}

	public static int getFriendNumMax() {
		return friendNumMax;
	}

	public static String getLocaleResource() {
		return localeResource;
	}

	public static int getMailContentLength() {
		return mailContentLength;
	}

	public static int getMailContentLengthMax() {
		return mailContentLengthMax;
	}

	public static int getMailTitleLength() {
		return mailTitleLength;
	}

	public static int getMailTitleLengthMax() {
		return mailTitleLengthMax;
	}

	public static int getNameLength() {
		return nameLength;
	}

	public static int getNameLengthMax() {
		return nameLengthMax;
	}
	@Deprecated
	public static String[] getPrestigeNames() {
		return prestigeNames;
	}

	public static int[] getPrestigeValues() {
		return prestigeValues;
	}

	public static int[] getShopHotIds() {
		return shopHotIds;
	}

	public static int[] getShopNewIds() {
		return shopNewIds;
	}

	public static int getSysAccessFlag() {
		return sysAccessFlag;
	}

	public static int getSysAysncSpeedMinute() {
		return sysAysncSpeedMinute;
	}

	public static int getSysAysncThreads() {
		return sysAysncThreads;
	}
	
	public static int getSysCgAtivity() {
		return sysCgAtivity;
	}

	public static int getSysCgAutoNumberSuffix() {
		return sysCgAutoNumberSuffix;
	}

	public static List<String> getSysCgCrossIP() {
		return sysCgCrossIP;
	}

	public static String getSysCgCrossURL() {
		return sysCgCrossURL;
	}
	
	public static int getSysCgCrossServiceId() {
		return sysCgCrossServiceId;
	}

	public static int getSysCgGcLevel() {
		return sysCgGcLevel;
	}

	public static String getSysCgKeyLogin() {
		return sysCgKeyLogin;
	}

	public static String getSysCgKeyPay() {
		return sysCgKeyPay;
	}

	public static String getSysCgKeyPlatform() {
		return sysCgKeyPlatform;
	}

	public static int getSysCgOpenTime() {
		if (BlankUtils.isBlank(sysCgOpenTime)) {
			return TimeProcesser.getUnixTime();
		} else {
			return TimeProcesser.getUnixTime(DateFormatUtils.parseDateTime(sysCgOpenTime));
		}
	}

	public static String getSysCgPartnerEName() {
		return sysCgPartnerEName;
	}

	public static int getSysCgPayRate() {
		return sysCgPayRate;
	}

	public static int getSysCgServiceId() {
		return sysCgServiceId;
	}

	public static String getSysCgSvrId() {
		return sysCgSvrId;
	}

	public static int getSysCgWorldId() {
		return sysCgWorldId;
	}

	public static Set<String> getSysGmAccountName() {
		return sysGmAccountName;
	}

	public static List<String> getSysGmIp() {
		return sysGmIp;
	}

	public static int getSysInspectComm() {
		return sysInspectComm;
	}

	public static Set<Long> getSysInstructor() {
		return sysInstructor;
	}

	public static Map<Long, Integer> getSysLockChat() {
		return sysLockChat;
	}

	public static List<String> getSysLockIp() {
		return sysLockIp;
	}

	public static Map<Long, Integer> getSysLockPlayerId() {
		return sysLockPlayerId;
	}

	public static List<String> getSysLockChatIP() {
		return sysLockChatIP;
	}

	public static List<String> getSysLockChatAcc() {
		return sysLockChatAcc;
	}

	public static int getSysSubLineNum() {
		return sysSubLineNum;
	}

	public static int getSysSubLineOverflow() {
		return sysSubLineOverflow;
	}

	public static int getSysSubLinePlayers() {
		return sysSubLinePlayers;
	}

	public static int getTaskAcceptMax() {
		return taskAcceptMax;
	}

	public static int getTaskDayNumsDaily() {
		return taskDayNumsDaily;
	}

	public static int getTaskDayNumsDart() {
		return taskDayNumsDart;
	}

	public static int getTaskDayNumsPrestige() {
		return taskDayNumsPrestige;
	}

	public static int getTaskDayNumsUnion() {
		return taskDayNumsUnion;
	}

	public static int getUnionCreateAsset() {
		return unionCreateAsset;
	}
	public static int[] getUnionJobsFlag() {
		return unionJobsFlag;
	}

	public static int getUnionNameLength() {
		return unionNameLength;
	}

	public static int getUnionNameLengthMax() {
		return unionNameLengthMax;
	}

	public static List<String> getSysGmInstructor() {
		return sysGmInstructor;
	}

	public static boolean isLocalHost() {
		return sysCgPartnerEName.equals("localhost");
	}

	public static boolean isSysClosed() {
		return sysClosed;
	}

	public static boolean isSysInspectAddicted() {
		return sysInspectAddicted;
	}

	public static boolean isSysInspectMove() {
		return sysInspectMove;
	}

	public static boolean isSysInspectScene() {
		return sysInspectScene;
	}

	public synchronized static void load() throws Exception {

		Map<String, String> map = Context.getCongfigServer().loadConfigFromDb();

		Field[] fields = ConstantsConfig.class.getDeclaredFields();
		for (Field e : fields) {

			int modifiers = e.getModifiers();
			if (!Modifier.isStatic(modifiers)) {
				continue;
			}
			if (Modifier.isFinal(modifiers)) {
				continue;
			}

			String name = e.getName();
			if (map.containsKey(name)) {
				setValue(e, map.get(name).toString());
			}
		}
	}

	/**
	 * 解析配置，发现旧数据删除并同步数据库
	 * 
	 * @param playerIds
	 * @return
	 */
	public static List<ModeRecordVO> parse(Map<Long, Integer> playerIds, String keyNames) {
		List<ModeRecordVO> records = new ArrayList<ModeRecordVO>();

		if (!BlankUtils.isBlank(playerIds)) {
			boolean change = false;
			Iterator<Long> iterator = playerIds.keySet().iterator();
			while (iterator.hasNext()) {
				long playerId = iterator.next();
				Integer endTime = playerIds.get(playerId);
				Player p = Context.getPlayerServer().getByPlayerId(playerId);
				if (TimeProcesser.getUnixTime() >= endTime || p == null) {
					change = true;
					iterator.remove();
				} else {
					ModeRecordVO record = new ModeRecordVO();
					record.setPlayerId(p.getPlayerId());
					record.setPlayerName(p.getPlayerName());
					record.setAccountName(p.getAccountName());
					record.setEndTime(endTime);
					records.add(record);
				}
			}

			// 更新同步数据库
			if (change) {
				Context.getBusinessServer().updateConfig(keyNames, ConstantsConfig.format(playerIds));
			}
		}

		return records;
	}

	public static void setSysCgGcLevel(int sysCgGcLevel) {
		ConstantsConfig.sysCgGcLevel = sysCgGcLevel;
	}

	public static void setSysClosed(boolean sysClosed) {
		ConstantsConfig.sysClosed = sysClosed;
	}

	public static void setValue(Field e, String configValue) {
		Object valueObject = configValue;
		if (e.getType() == int.class || e.getType() == Integer.class) {
			valueObject = Integer.valueOf(configValue);
		} else if (e.getType() == boolean.class) {
			valueObject = Integer.valueOf(configValue) > 0;
		} else if (e.getType() == String.class) {
			// valueObject = configValue;
		} else if (e.getType() == String[].class) {
			valueObject = configValue.split(Constants.COMMSPLIT);
		} else if (e.getType() == int[].class || e.getType() == Integer[].class) {
			valueObject = StringProcesser.toIntArray(configValue);
		} else if (e.getType() == List.class) {// 类型写死了.
			Type aType = getCollectionType(e);
			String splitString = Constants.COMMSPLIT;
			if (e.getName().equals("sysLockIp") || e.getName().equals("sysGmIp") || e.getName().equals("sysCgCrossIP") || e.getName().equals("sysLockChatAcc")
					|| e.getName().equals("sysLockChatIP")) {
				splitString = "\n";
				configValue = configValue.replace("\r", "");
			}

			String[] strings = configValue.split(splitString);
			List<String> wordList = new ArrayList<String>();
			boolean lowerCase = e.getName().equals("adWorld");// 广告词小写
			if (aType == String.class) {
				for (String world : strings) {
					if (world.trim().length() == 0) {
						continue;
					}
					wordList.add(lowerCase ? world.trim().toLowerCase() : world.trim());
				}
			} else if (aType == int.class || aType == Integer.class) {
				return;
			} else {
				return;
			}
			valueObject = wordList;
		} else if (e.getType() == Set.class) {
			Type aType = getCollectionType(e);

			String[] strings = configValue.split(Constants.COMMSPLIT);
			if (aType == String.class) {
				Set<String> wordList = new HashSet<String>();
				for (String world : strings) {
					wordList.add(world);
				}
				valueObject = wordList;
			} else if (aType == long.class || aType == Long.class) {
				Set<Long> wordList = new HashSet<Long>();
				for (String world : strings) {
					wordList.add(Long.valueOf(world));
				}
				valueObject = wordList;
			} else {
				return;
			}
		} else if (e.getType() == Map.class) {
			String[] strings = configValue.replaceAll("\r", "").split("\n");
			Map<Long, Integer> wordList = new HashMap<Long, Integer>();
			for (String world : strings) {
				if (world == null || world.length() <= 1) {
					continue;
				}
				String[] s = world.split("\\:");
				wordList.put(Long.valueOf(s[0]), Integer.valueOf(s[1]));
			}
			valueObject = wordList;
		} else {
			return;
		}
		try {
			e.set(null, valueObject);
		} catch (IllegalArgumentException e1) {
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			e1.printStackTrace();
		}
	}

	public static boolean isInspectComm(int type) {
		return (sysInspectComm & type) > 0;
	}

}
